package de.karlNet.condition.conditions;

import java.lang.reflect.Array;

public abstract class Condition<T> implements IIsMet<T> {
	protected final T[] actualValues;
	protected T[] valuesToBeExpected;

	public Condition(T... actualValues) {
		super();
		this.actualValues = actualValues;
	}

	public Condition(T[] actualValues, T[] valuesToBeExpected) {
		super();
		this.actualValues = actualValues;
		this.valuesToBeExpected = valuesToBeExpected;
		assert (actualValues.length == valuesToBeExpected.length);
	}

	protected boolean meets() {
		assert (actualValues.length == valuesToBeExpected.length);
		return true;
	}

	@SuppressWarnings("unchecked")
	public boolean meetsNull() {
		this.valuesToBeExpected = (T[]) Array.newInstance(
				new Object().getClass(), this.actualValues.length);
		for (int i = 0; i < this.actualValues.length; i++) {
			this.valuesToBeExpected[i] = null;
		}
		return this.meets();
	}
	
	public boolean meetsNullOrEmpty() {
		return false;
	}

	public boolean meets(T... valuesToExpect) {
		if (valuesToExpect.length == 1) {
			T valueToExpect = valuesToExpect[0];
			this.valuesToBeExpected = (T[]) Array.newInstance(
					valueToExpect.getClass(), this.actualValues.length);
			for (int i = 0; i < this.actualValues.length; i++) {
				this.valuesToBeExpected[i] = valueToExpect;
			}
		} else {
			this.valuesToBeExpected = valuesToExpect;
		}
		return this.meets();
	}

	public void meets(Runnable toBeExecuted) {
		if (this.meets()) {
			toBeExecuted.run();
		}
	}

	public void meets(Runnable ifSo, Runnable elseSo, T... valuesToExpect) {
		if (this.meets(valuesToExpect)) {
			ifSo.run();
		} else {
			elseSo.run();
		}
	}

	public void meets(Runnable toBeExecuted, T... valuesToExpect) {
		if (this.meets(valuesToExpect)) {
			toBeExecuted.run();
		}
	}

}
